﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using BSCMFF.Core;
using BSCMFF.Core.BusinessLayer;
using Telerik.Web.UI;
using BSCMFF.Core.DataAccessLayer;
using BSCMFF.Core.Exceptions.Database;
using System.Collections;

namespace BSCMFF.Web.Pages.BSC_Setup.Manager
{
    public partial class BSCProgress : MultiLanguagePage
    {
        protected void Page_Init(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                RadCalendar1.SelectedDate = DateTime.Today;
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {


            if (!IsPostBack)
            {
                //RadTreeList1.ExpandedIndexes.Add(new TreeListHierarchyIndex { LevelIndex = 0, NestedLevel = 0 });
                //RadTreeList1.ExpandedIndexes.Add(new TreeListHierarchyIndex { LevelIndex = 1, NestedLevel = 0 });
                //RadTreeList1.ExpandedIndexes.Add(new TreeListHierarchyIndex { LevelIndex = 2, NestedLevel = 0 });


                RadTreeList1.ExpandAllItems();

                //TreeListDataItem item = RadTreeList1.Items[0];
                //item.Selected = true;

            }
        }

        private List<BSCTreeListItem> bscdata;
        protected void RadTreeList1_NeedDataSource(object sender, TreeListNeedDataSourceEventArgs e)
        {
            //RadTreeList1.DataSource = MyData.GetData();
            //RadTreeList1.DataSource = BSCTreeListManager.GetData();
            //RadTreeList1.DataSource = BSCTreeListManager.GetDataByDate(DateTime.Today.AddDays(-1));
            //if (RadCalendar1.SelectedDate == null)
            //{
            //    RadTreeList1.DataSource = BSCTreeListManager.GetDataByDate(DateTime.Today);
            //}
            //else
            //{
            bscdata = BSCTreeListManager.GetDataByDate(RadCalendar1.SelectedDate);
            RadTreeList1.DataSource = bscdata;

            CheckWeights(bscdata);
            //}
        }

        private void CheckWeights(List<BSCTreeListItem> bscdata)
        {

            int totalWeight = 0;
            foreach (var it in bscdata)
            {
                if (it.ItemType == "KPI")
                {
                    totalWeight += Int32.Parse(it.Weight);
                }
            }

            if (totalWeight != 100)
            {
                PanelWarning.Visible = true;
                LabelWeightsWarning.Text = "Sum of weights have to be 100%. Currenty it is " + totalWeight.ToString() + "%";
                LabelWeightsWarning.ForeColor = System.Drawing.Color.Red;
            }
            else
            {
                PanelWarning.Visible = false;
            }
        }

        protected void RadButtonAssignWeights_Click(object sender, EventArgs e)
        {
            BSCEntities context = new BSCEntities();
            if (RadCalendar1.SelectedDate == DateTime.Today)
            {
                List<KPI> kpis = (from kpi in context.KPIs
                                  select kpi).ToList();


                int averageUp = (int)Math.Ceiling((decimal)(100 / (decimal)kpis.Count));
                int averageDown = (int)Math.Floor((decimal)(100 / (decimal)kpis.Count));

                int totalSoFar = 0;
                for (int i = 0; i < kpis.Count - 1; ++i)
                {
                    int average = i % 2 == 0 ? averageUp : averageDown;
                    kpis[i].Weight = average;
                    totalSoFar += average;
                }
                if (kpis.Count >= 2)
                {
                    kpis[kpis.Count - 1].Weight = 100 - totalSoFar;
                }

                try
                {
                    context.SaveChanges();
                    RadTreeList1.Rebind();
                }
                catch (Exception ex)
                {
                    throw new InconsistentDatabaseException("Couldn't even weights: " + ex.Message);
                }
            }
        }

        protected void RadTreeList1_ItemDataBound(object sender, TreeListItemDataBoundEventArgs e)
        {
            if (e.Item is TreeListDataItem)
            {
                TreeListDataItem item = e.Item as TreeListDataItem;
                if (item.HierarchyIndex.NestedLevel == 0)
                {
                    (item.FindControl("img") as Image).ImageUrl = "~/Images/149881-bsc-designer-pro.gif";
                    if (RadCalendar1.SelectedDate > DateTime.Today)
                    {
                        item["Select"].Controls[0].Visible = false;
                    }
                    item["Edit"].Controls[0].Visible = false;
                }
                if (item.HierarchyIndex.NestedLevel == 1)
                {
                    (item.FindControl("img") as Image).ImageUrl = "~/Images/Root.GIF";

                    item.BackColor = System.Drawing.ColorTranslator.FromHtml("#B5D6FD");
                    //item["Select"].Controls[0].Visible = false;
                    item["Edit"].Controls[0].Visible = false;
                    if (RadCalendar1.SelectedDate > DateTime.Today)
                    {
                        item["Select"].Controls[0].Visible = false;
                    }

                }
                if (item.HierarchyIndex.NestedLevel == 2)
                {
                    (item.FindControl("img") as Image).ImageUrl = "~/Images/KPI Drilling/graph Icon.jpg";
                    item.BackColor = System.Drawing.ColorTranslator.FromHtml("#D7F5FF");
                    if (RadCalendar1.SelectedDate > DateTime.Today)
                    {
                        item["Edit"].Controls[0].Visible = false;
                    }
                    if (RadCalendar1.SelectedDate > DateTime.Today)
                    {
                        item["Select"].Controls[0].Visible = false;
                    }

                }
                //long value = (long)DataBinder.Eval(item.DataItem, "Population");
                //item["Name"].BackColor = System.Drawing.Color.White;
            }
        }

        protected void RadCalendar1_SelectionChanged(object sender, Telerik.Web.UI.Calendar.SelectedDatesEventArgs e)
        {
            RadTreeList1_NeedDataSource(sender, new TreeListNeedDataSourceEventArgs(TreeListRebindReason.PostBackEvent));

        }

        protected void RadTreeList1_ItemCommand(object sender, TreeListCommandEventArgs e)
        {
            if (e.CommandName == RadTreeList.SelectCommandName)
            {
                //BSCTreeListItem bli = bscdata[
                TreeListDataItem editedItem = (e.Item as TreeListDataItem);

                switch (editedItem["ItemType"].Text)
                {
                    case "KPI": ShowKPI(editedItem); break;
                    case "Perspective": ShowPerspective(editedItem); break;
                    default: ShowBSC_new(); break;
                }

                //(DKPI.FindControl("TextBoxName") as RadTextBox).Text = editedItem["Name2"].Text; 

                //DKPI.Visible = true;

                ////(userControl.FindControl("Name") as RadTextBox).Text = tlda[editedItem.DisplayIndex]["Name"].ToString();
                ////string dataKeyValue = editedItem.ParentItem.GetDataKeyValue("EmployeeID").ToString();

                //ShowProgress(editedItem["ID"].Text);
            }

        }

        private void ShowBSC_new()
        {
            BSCEntities context = new BSCEntities();

            DateTime selecteDate = RadCalendar1.SelectedDate;
            DateTime week = selecteDate.AddDays(-14); // DateTime.Today.AddDays(-14);

            var data = (from kp in context.KPI_Progress
                        where kp.Date < selecteDate && kp.Date >= week
                        group kp by new { kp.Date } into g
                        select new
                        {
                            Date = g.Key.Date,
                            Progress = (int)g.Sum(kp => (kp.Current_Value - kp.Start_Value) * kp.Weight / (kp.Target_Value - kp.Start_Value) * 100) / g.Count() / g.Sum(kp => kp.Weight),
                            //progress2 = g.Select(prog => prog.Progress * prog.Weight)

                        }).ToList();


            int numberOfDates = 0;
            if (data.Count > 14)
            {
                numberOfDates = 14;
            }
            else
            {
                numberOfDates = data.Count;
            }
            RadChart1.PlotArea.XAxis.AutoScale = false;
            RadChart1.PlotArea.XAxis.AddRange(1, numberOfDates, 1);

            for (int i = 0; i < data.Count; ++i)
            {

                RadChart1.PlotArea.XAxis[i].TextBlock.Text = data[i].Date.ToShortDateString();//.ToShortDateString();
                RadChart1.PlotArea.XAxis.Appearance.LabelAppearance.RotationAngle = -45;
                //RadChart1.PlotArea.XAxis.Appearance.LabelAppearance.Position.Y = 100;
                RadChart1.PlotArea.XAxis.Appearance.LabelAppearance.Position.AlignedPosition = Telerik.Charting.Styles.AlignedPositions.Top;
            }
            const int markedZoneSize = 15;
            RadChart1.PlotArea.MarkedZones[0].ValueStartY = 0 - markedZoneSize;
            RadChart1.PlotArea.MarkedZones[0].ValueEndY = 0;
            RadChart1.PlotArea.MarkedZones[0].Label.TextBlock.Text = "";
            RadChart1.PlotArea.MarkedZones[1].Label.TextBlock.Text = "";
            RadChart1.PlotArea.MarkedZones[1].ValueStartY = 100 + markedZoneSize;
            RadChart1.PlotArea.MarkedZones[1].ValueEndY = 100;

            RadChart1.DataSource = data;
            //RadChart1.PlotArea.XAxis.DataLabelsColumn = "Date";
            RadChart1.DataBind();
            RadChart1.Series[0].Appearance.LineSeriesAppearance.Color = System.Drawing.Color.Blue;
            RadChart1.PlotArea.Appearance.Dimensions.Margins.Bottom = 100;


            RadChart1.ChartTitle.TextBlock.Text = "BSC";
        }

        private void ShowKPI(TreeListDataItem editedItem)
        {
            ShowKPIProgress(editedItem["ID"].Text);


        }

        private void ShowPerspective(TreeListDataItem editedItem)
        {
            //(DKPI.FindControl("TextBoxName") as RadTextBox).Text = editedItem["Name2"].Text;
            //(DKPI.FindControl("RadNumericTextBoxWeight") as RadNumericTextBox).Value = Convert.ToInt32(editedItem["Weight"].Text);
            //DPerspective.Visible = true;

            //ShowPerspectiveProgress(editedItem["ID"].Text);
            ShowPerspectiveProgress_new(editedItem["ID"].Text);
        }


        private void ShowBSC()
        {
            BSCEntities context = new BSCEntities();

            var data = (from kp in context.KPI_Progress
                        where kp.Date <= DateTime.Today
                        group kp by new { kp.Date } into g
                        select new
                        {
                            progress = g.Select(prog => prog.Progress * prog.Weight)
                        }).ToList();
            //orderby kp.Date
            //select new { kp.Date, kp.Current_Value, kp.Start_Value, kp.Target_Value }).ToList();
            RadChart1.Series.RemoveSeries();

            RadChart1.DataSource = data;
            RadChart1.DataBind();
        }


        private void ShowKPIProgress(string p)
        {
            BSCEntities context = new BSCEntities();

            int kpi_id = Convert.ToInt32(p);

            KPI kpi = (from kpis in context.KPIs
                       where kpis.KPI_ID == kpi_id
                       select kpis).SingleOrDefault();

            int diff = (int)(kpi.Max - kpi.Min);

            const int markedZoneSize = 10;
            RadChart1.PlotArea.MarkedZones[0].ValueStartY = kpi.Min - markedZoneSize;
            RadChart1.PlotArea.MarkedZones[0].ValueEndY = kpi.Min;
            RadChart1.PlotArea.MarkedZones[0].Label.TextBlock.Text = "";
            RadChart1.PlotArea.MarkedZones[1].Label.TextBlock.Text = "";
            RadChart1.PlotArea.MarkedZones[1].ValueStartY = kpi.Max + markedZoneSize;
            RadChart1.PlotArea.MarkedZones[1].ValueEndY = kpi.Max;

            RadChart1.PlotArea.YAxis.MinValue = kpi.Min - markedZoneSize;
            RadChart1.PlotArea.YAxis.MaxValue = kpi.Max + markedZoneSize;

            RadChart1.PlotArea.YAxis.LabelStep = 1;

            DateTime selecteDate = RadCalendar1.SelectedDate;
            DateTime week = selecteDate.AddDays(-14); // DateTime.Today.AddDays(-14);

            var data = (from kp in context.KPI_Progress
                        where kp.KPI_FK == kpi_id && kp.Date < selecteDate && kp.Date >= week
                        orderby kp.Date
                        //select new { kp.Date, kp.Current_Value, kp.Start_Value, kp.Target_Value, kp.Min, kp.Max }).Take(20).ToList();
                        select new { kp.Date, kp.Current_Value, kp.Start_Value, kp.Target_Value }).Take(20).ToList();

            int numberOfDates = 0;
            if (data.Count > 14)
            {
                numberOfDates = 14;
            }
            else
            {
                numberOfDates = data.Count;
            }
            RadChart1.PlotArea.XAxis.AutoScale = false;
            RadChart1.PlotArea.XAxis.AddRange(1, numberOfDates, 1);

            for (int i = 0; i < data.Count; ++i)
            {

                RadChart1.PlotArea.XAxis[i].TextBlock.Text = data[i].Date.ToShortDateString();//.ToShortDateString();
                RadChart1.PlotArea.XAxis.Appearance.LabelAppearance.RotationAngle = -45;
                //RadChart1.PlotArea.XAxis.Appearance.LabelAppearance.Position.Y = 100;
                RadChart1.PlotArea.XAxis.Appearance.LabelAppearance.Position.AlignedPosition = Telerik.Charting.Styles.AlignedPositions.Top;
            }

            RadChart1.DataSource = data;
            //RadChart1.PlotArea.XAxis.DataLabelsColumn = "Date";
            RadChart1.DataBind();

            RadChart1.Series[1].Appearance.ShowLabels = false;
            RadChart1.Series[2].Appearance.ShowLabels = false;

            RadChart1.Series[0].Appearance.LineSeriesAppearance.Color = System.Drawing.Color.Blue;
            RadChart1.Series[1].Appearance.LineSeriesAppearance.Color = System.Drawing.Color.Red;
            RadChart1.Series[2].Appearance.LineSeriesAppearance.Color = System.Drawing.Color.Green;
            RadChart1.PlotArea.Appearance.Dimensions.Margins.Bottom = 100;


            RadChart1.ChartTitle.TextBlock.Text = "KPI: " + kpi.Name;
        }

        private void ShowPerspectiveProgress_new(string p)
        {
            BSCEntities context = new BSCEntities();

            int perspective_id = Convert.ToInt32(p);
            DateTime selecteDate = RadCalendar1.SelectedDate;
            DateTime week = selecteDate.AddDays(-14); // DateTime.Today.AddDays(-14);

            var data = (from kp in context.KPI_Progress
                        join k in context.KPIs on kp.KPI_FK equals k.KPI_ID
                        where k.Perspective_FK == perspective_id && kp.Date < selecteDate && kp.Date >= week
                        group kp by new { kp.Date } into g
                        select new
                        {
                            Date = g.Key.Date,
                            Progress = (int)g.Sum(kp => (kp.Current_Value - kp.Start_Value) * kp.Weight / (kp.Target_Value - kp.Start_Value) * 100) / g.Count() / g.Sum(kp => kp.Weight),
                            //progress2 = g.Select(prog => prog.Progress * prog.Weight)

                        }).ToList();


            int numberOfDates = 0;
            if (data.Count > 14)
            {
                numberOfDates = 14;
            }
            else
            {
                numberOfDates = data.Count;
            }
            RadChart1.PlotArea.XAxis.AutoScale = false;
            RadChart1.PlotArea.XAxis.AddRange(1, numberOfDates, 1);

            for (int i = 0; i < data.Count; ++i)
            {

                RadChart1.PlotArea.XAxis[i].TextBlock.Text = data[i].Date.ToShortDateString();//.ToShortDateString();
                RadChart1.PlotArea.XAxis.Appearance.LabelAppearance.RotationAngle = -45;
                //RadChart1.PlotArea.XAxis.Appearance.LabelAppearance.Position.Y = 100;
                RadChart1.PlotArea.XAxis.Appearance.LabelAppearance.Position.AlignedPosition = Telerik.Charting.Styles.AlignedPositions.Top;
            }
            const int markedZoneSize = 15;
            RadChart1.PlotArea.MarkedZones[0].ValueStartY = 0 - markedZoneSize;
            RadChart1.PlotArea.MarkedZones[0].ValueEndY = 0;
            RadChart1.PlotArea.MarkedZones[1].ValueStartY = 100 + markedZoneSize;
            RadChart1.PlotArea.MarkedZones[1].ValueEndY = 100;

            RadChart1.DataSource = data;
            //RadChart1.PlotArea.XAxis.DataLabelsColumn = "Date";
            RadChart1.DataBind();
            RadChart1.Series[0].Appearance.LineSeriesAppearance.Color = System.Drawing.Color.Blue;
            RadChart1.PlotArea.Appearance.Dimensions.Margins.Bottom = 100;

            Perspective persp = (from ps in context.Perspectives
                                 where ps.Perspective_ID == perspective_id
                                 select ps).SingleOrDefault();

            RadChart1.ChartTitle.TextBlock.Text = persp.Name + " Perspective";

        }

        private void ShowPerspectiveProgress(string p)
        {
            BSCEntities context = new BSCEntities();

            int perspective_id = Convert.ToInt32(p);

            var data = (from k in context.KPIs
                        where k.Perspective_FK == perspective_id
                        from kp in context.KPI_Progress
                        where kp.KPI_FK == k.KPI_ID && kp.Date <= DateTime.Today
                        // group kp by kp.da
                        orderby kp.Date
                        select kp).ToList();

            //Hashtable ht = CalculatePerspectiveProgress(data);


            Dictionary<DateTime, int> weights = new Dictionary<DateTime, int>();
            Dictionary<DateTime, double> progress = new Dictionary<DateTime, double>();
            Hashtable progress2 = new Hashtable();
            foreach (var d in data)
            {
                if (!weights.ContainsKey(d.Date))
                {
                    weights[d.Date] = d.Weight;
                    //progress[d.Date] = d.Weight * d.Progress;
                    progress2[d.Date] = d.Weight * d.Progress;
                }
                else
                {
                    weights[d.Date] += d.Weight;
                    //progress[d.Date] += d.Weight * d.Progress;
                    progress2[d.Date] = (double)progress2[d.Date] + d.Weight * d.Progress;
                }
            }

            Hashtable progressdivided = new Hashtable();
            foreach (var pr in progress2)
            {
                string s = pr.ToString();
                //= pr.Value / weights[pr.Key];
                //DictionaryEntry de = new DictionaryEntry();
                //de["asd"] = (float)((DictionaryEntry)pr).Value / weights[(DateTime)((DictionaryEntry)pr).Key];
                //((DictionaryEntry)pr).Value = (float)((DictionaryEntry)pr).Value / weights[(DateTime)((DictionaryEntry)pr).Key];

                progressdivided[((DictionaryEntry)pr).Key] = Convert.ToDouble(((DictionaryEntry)pr).Value) / (int)(weights[Convert.ToDateTime(((DictionaryEntry)pr).Key.ToString())]);
            }


            //data[0].Date;
            RadChart1.Series.RemoveSeries();
            RadChart1.DataSource = progressdivided;
            RadChart1.DataBind();

        }

        protected void RadTreeList1_UpdateCommand(object sender, TreeListCommandEventArgs e)
        {
            //Canceling out the automatic datasource operation (needed if you use a datasource control)
            e.Canceled = true;
            //Accessing the TreeListEditFormItem and the DataKeyValue of the edited row
            TreeListEditFormItem editedItem = (e.Item as TreeListEditFormItem);
            int kpiID = Int32.Parse(editedItem.ParentItem.GetDataKeyValue("ID").ToString());

            //Extracting the values from the edit form
            int weight = (int)(editedItem.FindControl("RadNumericTextBoxWeight") as RadNumericTextBox).Value;
            double start = (double)(editedItem.FindControl("RadNumericTextBoxStartValue") as RadNumericTextBox).Value;
            double target = (double)(editedItem.FindControl("RadNumericTextBoxTargetValue") as RadNumericTextBox).Value;
            double? current = (editedItem.FindControl("RadNumericTextBoxCurrentValue") as RadNumericTextBox).Value;

            double? min = (editedItem.FindControl("RadNumericTextBoxMin") as RadNumericTextBox).Value;
            double? max = (editedItem.FindControl("RadNumericTextBoxMax") as RadNumericTextBox).Value;

            BSCEntities context = new BSCEntities();

            if (RadCalendar1.SelectedDate == DateTime.Today)
            {
                KPI kpi = (from kpis in context.KPIs
                           where kpis.KPI_ID == kpiID
                           select kpis).SingleOrDefault();

                kpi.Weight = weight;
                kpi.Start_Value = start;
                kpi.Target_Value = target;
                kpi.Current_Value = current == null ? start : (double)current;

                kpi.Min = min == null ? start : (double)min;
                kpi.Max = max == null ? target : (double)max;
            }
            else
            {
                KPI_Progress kpip = (from kpips in context.KPI_Progress
                                     where kpips.KPI_FK == kpiID && kpips.Date == RadCalendar1.SelectedDate
                                     select kpips).SingleOrDefault();

                //if (kpip == null)
                //{
                //    kpip = new KPI_Progress();
                //    kpip.KPI_FK = kpiID;

                //    context.AddToKPI_Progress(kpip);
                //}

                kpip.Weight = weight;
                kpip.Start_Value = start;
                kpip.Target_Value = target;
                kpip.Current_Value = current == null ? start : (double)current;

                kpip.Min = min == null ? start : (double)min;
                kpip.Max = max == null ? target : (double)max;
            }


            try
            {
                context.SaveChanges();
            }
            catch (Exception ex)
            {
                throw new InconsistentDatabaseException("Couldn't update KPI progress : " + ex.Message);
            }


            //Closing the edit form and rebinding the treelist control
            RadTreeList1.EditIndexes.Clear();
            //RadTreeList1.
            RadTreeList1.Rebind();
        }

        protected void Calendar1_DayRender(object sender, Telerik.Web.UI.Calendar.DayRenderEventArgs e)
        {
            if (e.Day.Date > DateTime.Today)
            {
                e.Day.IsSelectable = false;
            }
        }

        //private Hashtable CalculatePerspectiveProgress(object data)
        //{

        //}

        //disable future dates
        //protected void Calendar1_DayRender(object sender, DayRenderEventArgs e)
        //{
        //    if (e.Day.Date > DateTime.Today)
        //    {
        //        e.Day.IsSelectable = false;
        //    }
        //}
    }
}